<?php

namespace App\Http\Services;

use App\Http\Model\Hint;
use App\Http\Model\OutJson;
use App\Http\Model\System;
use App\Http\Model\User;
use Godruoyi\Snowflake\Snowflake;
use Illuminate\Support\Facades\Log;
use App\Lib\Response;

/*公共service层*/

class CommonServices
{
    // TODO 默认全局参数【勿动】
    public $requestData = []; // 请求参数
    protected $verifyData = []; // 校验数据数组
    protected $paramDefaultData = []; // 默认值

    public $currentUser = [];// 当前用户信息
    public $currentUserId = 0;// 当前用户ID

    protected $user;
    protected $tokenName = 'user_token';
    public static $expire = 3600 * 24 * 7;

    public function __construct()
    {
        $this->user = new User();
        if (empty($this->currentUser) or empty($this->currentUserId)) {
            $getCurrentUser = $this->user->get_current_user();
            if (!empty($getCurrentUser) and !empty($getCurrentUser['user_id'])) {
                $this->currentUser = $getCurrentUser;
                $this->currentUserId = $getCurrentUser['user_id'];
            }
        }
    }

    //校验token
    public function checkToken()
    {
        $userInfo = $this->user->get_current_user();
        if (empty($userInfo) || empty($userInfo['user_id'])) {
            Response::returnResult(Hint::LOGIN_OUT);
        }
    }

    public function set_cross()
    {
        header("Access-Control-Allow-Origin:*");
    }

    /**
     * 从 UA 解析出[软件版本 | APP系统名 | 手机型号 | 渠道商ID]
     * @return array
     */
    public function parse_app_UA()
    {
        $originalUA = [];

        $userAgent = $_SERVER['HTTP_H5_USER_AGENT'] ?? $_SERVER['HTTP_USER_AGENT'] ?? '';
        if (!empty($userAgent)) {
            $originalUA = explode(';', $userAgent);
        }
        //安卓写错了只好这样纠正了
        $version_no = $originalUA[1] ?? '';
        $os_name = $originalUA[2] ?? '';
        if($version_no === "Android" || $version_no === "iPhone") {
            $version_no = $originalUA[2] ?? '';
            $os_name = $originalUA[1] ?? '';
        }

        return [
            'app' => $originalUA[0] ?? 'hypd',
            'version_no' => $version_no,
            'os_name' => $os_name,
            'device' => $originalUA[4] ?? '',
            'channel_id' => $originalUA[5] ?? '',
            'guid' => $originalUA[6] ?? ''
        ];
    }

    /**
     * 转换为驼峰式命名
     *
     * @param str 字符串
     * @ucfirst
     *          true 将首字母、下划线命名转换为驼峰式命名
     *          false 将下划线命名转换为驼峰式命名
     * */
    public function convertUnderline($str, $ucfirst = false)
    {
        $str = explode('_', $str);
        foreach ($str as $key => $val) {
            $str[$key] = ucfirst($val);
        }

        if (!$ucfirst) {
            $str[0] = strtolower($str[0]);
        }

        return implode('', $str);
    }

    /**
     * 初始化数值 增加校验属性
     *
     * 参数一: 字段名
     * 参数二: 字段注释
     * 参数三: 字符类型
     *                  i-数字,
     *                  s-字符,
     *                  a-数组,
     *                  si-校验数字类型,
     *                  ss-校验字符类型,
     *                  sa-校验数组类型
     * 参数四: 是否必选:TRUE(必选)/FALSE(非必选);
     * 参数五: 必选错误提示;
     * */
    public function I(...$params)
    {
        $field = '';
        foreach ($params as $key => $value) {
            switch ($key) {
                case 0; // 字段名
                    $field = $value;
                    break;
                case 1: // 字段注释
                    $this->verifyData[$field]['name'] = $value;
                    break;
                case 2: // 字段类型
                    $type = [
                        'int' => '',
                        'string' => '',
                        'array' => [],
                        'float' => 0,
                    ];
                    $this->paramDefaultData[$field] = $type[strtolower($value)] ?? '';
                    $this->verifyData[$field]['type'] = $value;
                    break;
                case 3: //是否必选
                    $this->verifyData[$field]['must'] = $value;
                    break;
                case 4: //必选错误描述
                    $this->verifyData[$field]['must_error'] = $value;
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * 初始化参数值
     * @param array $params 用作数据操作的数组
     * @param array $variables 修改键名的数组
     */
    public function check(&$params, &$variables = [])
    {
        do {
            $code = Hint::SUCCESS;
            $msg = Hint::getErrCodeMsg($code);

            // 请求参数
            $params = !is_array($params) ? [] : $params;
            $inputParams = $params;
            // 去除多余数据
            $params = array_intersect_key($params, $this->paramDefaultData);
            // 合并请求参数
            $params = array_merge($this->paramDefaultData, $params);

            foreach ($params as $key => $value) {

                // 每个参数对应校验规则
                if (!array_key_exists($key, $this->verifyData)) {
                    $code = Hint::ERR_PARAMS_CHECK_FAIL;
                    $msg = '校验规则初始化失败';
                    break;
                }

                // 字段名称
                $fieldName = $this->verifyData[$key]['name'] ?? '';
                // 字段类型
                $fieldType = $this->verifyData[$key]['type'] ?? '';
                // 字段必选项
                $fieldMust = $this->verifyData[$key]['must'] ?? false;
                // 错误描述
                $errorMsg = $this->verifyData[$key]['must_error'] ?? '';

                switch ($fieldType) {
                    case 'int':
                        if (!$fieldMust and $value === '') {
                            unset($params[$key]);
                            break;
                        }
                        if ($fieldMust and $value === '') {
                            if (empty($value) and !empty($errorMsg)) {
                                $code = Hint::ERR_PARAMS_CHECK_FAIL;
                                $msg = $errorMsg;
                                break;
                            } elseif (empty($value) and empty($errorMsg)) {
                                $code = Hint::ERR_PARAMS_CHECK_FAIL;
                                $msg = $fieldName . '数据校验未通过';
                                break;
                            }
                        }
                        if (!is_numeric($value)) {
                            $code = Hint::ERR_PARAMS_CHECK_FAIL;
                            $msg = $fieldName . '必须是数字类型';
                            break;
                        }
                        if (!array_key_exists($key, $inputParams)) {
                            unset($params[$key]);
                            break;
                        }

                        $value = intval($value);
                        $params[$key] = $value;
                        break;
                    case 'string':
                        if (is_null($value) or is_numeric($value)) {
                            $value = strval($value);
                        }
                        if (!is_string($value)) {
                            $code = Hint::ERR_PARAMS_CHECK_FAIL;
                            $msg = $fieldName . '必须是字符类型';
                            break;
                        }
                        $params[$key] = $value;
                        break;
                    case 'array':
                        if (!is_array($value)) {
                            $code = Hint::ERR_PARAMS_CHECK_FAIL;
                            $msg = $fieldName . '必须是数组';
                            break;
                        }
                        break;
                    default:
                        break;
                }

                if ($code != Hint::SUCCESS) {
                    break;
                }

                if (in_array($fieldType, ['string', 'array'])) {
                    if ($fieldMust and empty($value)) {
                        if (!empty($errorMsg)) {
                            $code = Hint::ERR_PARAMS_CHECK_FAIL;
                            $msg = $errorMsg;
                            break;
                        } else {
                            $code = Hint::ERR_PARAMS_CHECK_FAIL;
                            $msg = $fieldName . '数据校验未通过';
                            break;
                        }
                    }
                    if (!array_key_exists($key, $inputParams)) {
                        unset($params[$key]);
                        continue;
                    }
                }

            }

        } while (FALSE);

        // 参数置空
        $this->verifyData = [];
        $this->paramDefaultData = [];

        return compact('code', 'msg');
    }

    /**
     * 获取系统配置
     *
     * @return array|null
     */
    public function getSystemConfig()
    {
        return (new System())->get_config();
    }

}
